Skip to content

Offer the core under MIT OR Apache-2.0, and reverse the set that follows [#303] - #307

Merged
iderex merged 1 commit into
mainfrom
licence-answer-that-stands-303
Sep 5, 2026
Merged

Offer the core under MIT OR Apache-2.0, and reverse the set that follows [#303]#307
iderex merged 1 commit into
mainfrom
licence-answer-that-stands-303

Conversation

@iderex

@iderex iderex commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

The issue this belongs to

Closes #303

What changed

The core is offered under MIT OR Apache-2.0 from this commit, and the
dependency rule that derived its licence set from the earlier answer moves with
it.

docs/decisions/0303-the-licence-the-core-is-offered-under.md carries the
answer that stands, names the AGPL-3.0-or-later answer of 2026-08-24 that it
supersedes and the reason given for the one that replaced it, and supersedes
0103 rather than editing it. The outbound licence is the premise 0103
derives its licence set from, so under the answer that stands the one-way
compatibility runs the other way: every strength of copyleft moves to the
refused half, on two grounds the record keeps apart because only the first is a
compatibility fact. GPL, AGPL and LGPL impose conditions on the combined
work that a client offering their own client on their own terms cannot meet.
MPL-2.0 is satisfiable and is refused anyway, as a choice stated as one: it
carries a source-availability obligation into eleven client repositories that
MIT OR Apache-2.0 does not name, and accepting that obligation outbound while
refusing it inbound is a position that cannot be argued.

Everything in 0103 that does not rest on the outbound licence is carried
forward unchanged rather than dropped: the worth test, the five outright
behaviours with 0243's narrowing of the fourth written into it, the clause for
a requirement a landed record already states, the test-tree and shipping-tree
split, the removal rule and where the line beside a manifest entry lives.

0268 is re-read there rather than superseded. Its conjunction rule stands
untouched and is restated in the set. Unicode-3.0 stays in the admitted half
on the second of the two grounds that record gave - MIT already carries the
notice condition and the disclaimer, BSD-3-Clause already carries the
name-use bar, so no obligation class arrives with the term. The first ground
mapped those three conditions onto the supplementary terms AGPL-3.0-or-later
enumerates, quoting this repository's own licence file, and that mapping reads a
licence this work no longer carries.

The root carries LICENSE-MIT and LICENSE-APACHE and no longer carries the
AGPL text. Cargo.toml, README.md and NOTICE.md state the pair. README.md
also says what a copy already received under AGPL-3.0-or-later keeps, because
a licence is a grant to a recipient rather than a property of a repository and a
reader who had one should not have to work that out.

Pointers were added to three landed records and nothing in them was reworded:
0011 and 0091 each read the superseded answer out of the provider's listing,
and 0268's first ground reads the superseded licence file. Each gains one
sentence naming 0303, which is the pointer edit 0001 permits - remove any of
the three and the record says exactly what it said before. 0103 gains only the
superseded by half of its Status: line, which is the second permitted edit.

What failure it prevents

A client author checking the licence before writing a line against this core
found the answer that had been superseded, in four places at once. That has
already happened rather than being expected, and it is what #303 was opened
with:

git show origin/main:Cargo.toml | sed -n '8p'
license = "AGPL-3.0-or-later"
git show origin/main:README.md | sed -n '178p'
AGPL-3.0, copyright 2026 Nils Lehnen.
git show origin/main:LICENSE | sed -n '1,2p'
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007
gh api repos/Flowfin/core --jq '.license.spdx_id'
AGPL-3.0

The second failure is the dependency rule lagging behind the licence. A rule
whose stated ground is a licence the work is no longer offered under gets
applied in the permissive direction: a reader working from 0103's set admits a
copyleft node, the node lands, and a licence obligation is the one class of
mistake here that deleting the dependency later does not repair. Taking it today
costs nothing in the graph, which the reading below measures.

Evidence

The answer that stands, read out of the issue that holds it rather than from
this branch:

gh api repos/Flowfin/core/issues/1/comments \
  --jq '.[] | select(.created_at | startswith("2026-09-04T21:44")) | .body' | head -1
The answer of 2026-09-04 stands: MIT OR Apache-2.0. Entry 1 was answered twice because the second reading revisited it with the reason the first did not carry, that a core whose purpose is to be linked by clients this organisation does not write cannot be copyleft in any strength; the 2026-08-24 entry is superseded by that reading, and the record in docs/decisions/ says so in one sentence rather than leaving two answers on this issue for the next reader. Entries 2, 3 and 4 are unchanged. Label off; the record is the build.

The resolved graph, read at the commit being pushed. Nothing in it is admitted
only by the clause that moves:

git rev-parse HEAD
89b9102a0638eb63443f5dab1bbf352d6917f26b
cargo metadata --format-version 1 --locked \
  | jq -r '.packages[] | select(.name != "flowfin-core") | "\(.name) \(.version) \(.license)"' \
  | sort
base64 0.23.1 MIT OR Apache-2.0
block-buffer 0.12.1 MIT OR Apache-2.0
bytes 1.12.1 MIT
cfg-if 1.0.4 MIT OR Apache-2.0
cpufeatures 0.3.0 MIT OR Apache-2.0
crypto-common 0.2.2 MIT OR Apache-2.0
digest 0.11.3 MIT OR Apache-2.0
http 1.5.0 MIT OR Apache-2.0
httparse 1.10.1 MIT OR Apache-2.0
hybrid-array 0.4.14 MIT OR Apache-2.0
itoa 1.0.18 MIT OR Apache-2.0
libc 0.2.189 MIT OR Apache-2.0
log 0.4.34 MIT OR Apache-2.0
sha2 0.11.0 MIT OR Apache-2.0
typenum 1.20.1 MIT OR Apache-2.0
ureq-proto 0.6.1 MIT OR Apache-2.0

Sixteen packages, each a single admitted term or a dual offer both of whose
members are admitted.

LICENSE-APACHE is the canonical text and not a retyped one. Byte-identical to
what apache.org serves, at the commit being pushed:

curl -fsSL https://www.apache.org/licenses/LICENSE-2.0.txt -o /tmp/APACHE-canon.txt
sha256sum LICENSE-APACHE /tmp/APACHE-canon.txt
cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 *LICENSE-APACHE
cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 */tmp/APACHE-canon.txt

LICENSE-MIT is the SPDX text with the copyright line filled in and the
paragraphs wrapped; it is not byte-identical to any upstream file, and that is a
claim about a text a reader can compare rather than a measurement:

gh api repos/spdx/license-list-data/contents/text/MIT.txt --jq '.content' | base64 -d

The two commands CONTRIBUTING.md names, run on this branch:

cargo build --locked --all-targets
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.08s

cargo test --locked ; echo "exit=$?"
exit=0
grep -c '^test result: ok' /tmp/test-303.log
10

587, 2, 5, 5, 3, 11, 28, 5, 125 and 1 passing across the ten targets, none
failed, none ignored, none filtered out.

The gate legs that read what this change touches, run here:

bash .github/doc-paths/doc-paths.sh check
ok    78 document(s), 361 named path(s) resolved, 0 excused as examples

bash .github/decision-records/decision-records.sh check
Records: 66. Fields found: 6.
ok    6 field(s) name a record that exists, name a clause, and are named back

bash .github/format/format.sh check
      60 file(s) judged

bash .github/invariants/invariants.sh check
Every rule above was applied to its subject and refused nothing.

bash .github/lint/lint.sh check
Every lint the groups above carry was refused, outside the register printed with it.

bash .github/statements/statements.sh check
ok    every directive these registers carry has a statement, and every statement names a directive that exists

What this does not cover

No guard was added or edited, so there is nothing here to watch bite. Nothing
in this repository reads a licence expression, which 0103 already said of
itself and 0303 repeats: the set is applied by the review and by the line
beside a manifest entry. This change does not alter that and adds no check.

The two dependency entries in Cargo.toml still cite 0103 by number. They
are not rewritten here. Every statement they make about a licence is still true
under the successor - both members of MIT OR Apache-2.0 are in the admitted
half and ureq-proto's graph reaches no conjunction - so what is stale is the
number and not the judgement. 0303 names that residual in its own text under
"Where the line lives" rather than leaving a reader to find it.

What the provider's listing will report is not measured and is not claimed.
gh api repos/Flowfin/core --jq '.license.spdx_id' reads a state on GitHub
rather than a byte in this tree, that state is computed after the merge, and a
repository carrying two licence files may well come back as NOASSERTION rather
than as either member. #303's last condition asks that it stop reporting what
was superseded; whether it names something useful instead is GitHub's detector's
answer and not this change's. The reading will be taken on the issue after the
merge and written there whatever it says.

Whether the licence analysis is right is a judgement and no run here makes
one.
The two grounds for the refused half, the reading of MPL-2.0's third
section, and the re-reading of Unicode-3.0 against the new premise are
arguments in the record, written to be argued with. Nothing in this tree
evaluates them, and no lawyer has read them.

Nothing was run for a target other than this machine's. The targets and
cross-toolchain legs were not run here; this change compiles no code and
touches one manifest field, so nothing about a triple moves, but that is a claim
rather than a measurement.

cargo test --locked does not reach two targets, which is Cargo.toml's
own test = false on needs_a_real_server_or_real_hardware and
a_race_the_detector_must_catch. Neither was run here and neither is touched.

Who has read it

Nobody other than the author. There is no second reader on this board tonight,
and the evidence above stands in place of one.

…ows [#303]

Entry 1 of #1 was answered twice and the second answer stands: MIT OR
Apache-2.0, because a core whose purpose is to be linked by clients this
organisation does not write cannot be copyleft in any strength. The tree
published the first answer in four places at once - Cargo.toml, README.md, the
root LICENSE and the provider's own listing - so a client author following the
decision to the artefact found the opposite of what was decided, on the one
fact they check before writing a line against this core.

docs/decisions/0303-the-licence-the-core-is-offered-under.md carries the answer
that stands, names the 2026-08-24 answer it supersedes and the reason given for
the one that replaces it, and supersedes 0103 rather than editing it: the
outbound licence is the premise 0103 derives its licence set from, and under
MIT OR Apache-2.0 the one-way compatibility runs the other way. The whole
copyleft column moves to the refused half, on two grounds kept apart because
only the first is a compatibility fact - GPL, AGPL and LGPL impose conditions
on the combined work that a client offering their own client permissively
cannot meet, and MPL-2.0 is satisfiable but carries a source-availability
obligation into eleven client repositories that MIT OR Apache-2.0 does not name.
The worth test, the five outright behaviours with 0243's narrowing written into
the fourth, the clause for a standing requirement, the test-tree split and the
removal rule are carried forward unchanged.

0268 is re-read there rather than superseded. Its conjunction rule stands
untouched, and Unicode-3.0 stays admitted on the second of the two grounds it
gave - the admitted half already carries a notice condition and a name-use bar,
so no obligation class arrives with the term. The first ground mapped that
term's conditions onto the supplementary terms AGPL-3.0-or-later enumerates,
and that mapping reads a licence this work no longer carries.

The root now carries LICENSE-MIT and LICENSE-APACHE and no longer carries the
AGPL text; Cargo.toml, README.md and NOTICE.md state the pair. A copy already
received under AGPL-3.0-or-later keeps those terms, and README.md says so
rather than leaving a reader to wonder what happened to the licence they had.

Nothing in the resolved graph is admitted only by the clause that moves. The
sixteen packages and the expression each one carries are read into the record
under "The graph as it stands, read against this set", with the command that
produced the listing beside it, so the shrinking set costs this graph nothing
and that is measured rather than supposed.

Closes #303

Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com>
@iderex iderex added the legal Licensing, data protection, and the intended-use position label Sep 5, 2026
@iderex iderex self-assigned this Sep 5, 2026
@iderex iderex added this to the M1 Decisions of record milestone Sep 5, 2026
@iderex
iderex merged commit 27e4629 into main Sep 5, 2026
28 checks passed
@iderex
iderex deleted the licence-answer-that-stands-303 branch September 5, 2026 17:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

legal Licensing, data protection, and the intended-use position

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Carry the licence answer that stands into the tree, which publishes the one it supersedes

1 participant